package com.platform.component.excel.parser.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.platform.component.excel.parser.ExcelUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

import static org.apache.poi.ss.util.CellReference.NameType.ROW;

@Log4j2
public class ExcelParseHandler extends DefaultHandler {
    private final SharedStringsTable sst;

    private String lastContents;
    private boolean nextIsString;
    private String rowNo;

    /**
     * 记录总数, 正确数, 重复数, 错误数
     */
    private AtomicLong recordCnt;
    private AtomicLong errorCnt;

    /**
     * 行数据, 验证错误数据
     */
    private Map<String, String> rowData;

    private final List<List<String>> retList = Lists.newArrayList();
    private final List<String> tempList = Lists.newArrayList();

    public ExcelParseHandler(SharedStringsTable sst) {
        this.sst = sst;
    }

    @Override
    public void startElement(String uri, String localName, String name, Attributes attributes) {
        // 处理数据之前
        if (ExcelUtils.SHEET_DATA.equals(name)) {
            recordCnt = new AtomicLong();
            errorCnt = new AtomicLong();
        }

        // 行处理开始
        if (name.equalsIgnoreCase(String.valueOf(ROW))) {
            rowNo = attributes.getValue(ExcelUtils.ROW_NO);
            rowData = Maps.newHashMap();
            rowData.put(ExcelUtils.ERROR_DATA_FLAG, ExcelUtils.TRUE_FLAG);
        }

        if (ExcelUtils.CELL.equals(name)) {
            // Figure out if the value is an index in the SST
            String cellType = attributes.getValue(ExcelUtils.CELL_TYPE);
            nextIsString = ExcelUtils.CELL_TYPE_STRING.equals(cellType);
        }
        // Clear contents cache
        lastContents = "";
    }

    @Override
    public void endElement(String uri, String localName, String name) {
        handleEndTag(uri, localName, name);
    }

    private void handleEndTag(String uri, String localName, String name) {
        log.debug("uri:{},localName:{}", uri, localName);

        if (nextIsString) {
            int idx = Integer.parseInt(lastContents);
            lastContents = sst.getItemAt(idx).getString();
            nextIsString = false;
        }

        if (ExcelUtils.CELL_CONTENTS.equals(name) || ExcelUtils.CELL.equals(name)) {
            tempList.add(this.lastContents);
        }

        if ("row".equals(name) && Integer.parseInt(rowNo) <= 1000) {
            setRetList(tempList);
            tempList.clear();
            boolean isNullRow = rowData.size() == 1 && rowData.get(ExcelUtils.ERROR_DATA_FLAG).equals(ExcelUtils.TRUE_FLAG);
            // 避免读取空行
            if (!isNullRow) {
                recordCnt.incrementAndGet();
            }
        }

        // 文档处理结束
        if (ExcelUtils.SHEET_DATA.equals(name)) {
            // 如果有错误,导出错误数据
            if (errorCnt.get() > 0) {
                System.out.println("存在错误数据");
            }
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) {
        lastContents += new String(ch, start, length);
    }

    public List<List<String>> getRetList() {
        return retList;
    }

    public void setRetList(List<String> tmpList) {
        this.retList.add(new ArrayList<>(tmpList));
    }
}
